package com.fmy.mcsecurity.token;

import cn.hutool.core.util.StrUtil;
import com.fmy.mcsecurity.commons.tools.SecurityTool;
import com.fmy.mcsecurity.login.service.McUserDetails;
import com.fmy.mcsecurity.token.model.RefreshStorage;
import com.fmy.mcsecurity.token.model.SecurityToken;
import org.springframework.security.core.Authentication;

import java.util.List;

/**
 * @author Mr.fmy
 * @version 1.0.0
 * @ClassName DefultTokenManager
 * @Description TODO token管理类
 * @createTime 2019/10/23 13:34
 */
public class TokenManager {


    private final TokenGenerate tokenGenerate;

    private final TokenStorage tokenStorage;

    public TokenManager(TokenGenerate tokenGenerate, TokenStorage tokenStorage) {
        this.tokenGenerate = tokenGenerate;
        this.tokenStorage = tokenStorage;
    }

    public SecurityToken generate(String client, String type, Authentication authentication) {
        return tokenGenerate.generate(client, type, authentication);
    }

    public void save(String client, String type, Authentication authentication, SecurityToken token) {
        if (!(authentication.getPrincipal() instanceof McUserDetails)) {
            throw new IllegalArgumentException("UserDetails 请实现自定义的 JiUserDetails接口");
        } else {
            McUserDetails userDetails = (McUserDetails) authentication.getPrincipal();
            if (StrUtil.isBlank(userDetails.userId())) {
                throw new IllegalArgumentException("配置出错，未抓取到 userId");
            }
        }
        String user_id = ((McUserDetails) authentication.getPrincipal()).userId();
        String userKey = SecurityTool.userKey(client, user_id);

        if (tokenStorage.concurrency() > 0) {//限制通用户并发登录
            tokenStorage.setAuthenticationConcurrency(client, type, userKey, authentication, token);
        } else {
            tokenStorage.setAuthentication(client, type, userKey, authentication, token);
        }
    }

    public Authentication get(String userKey) {
        return tokenStorage.getAuthentication(userKey);
    }

    public void updateAuthentication(String userKey, Authentication authentication) {
        tokenStorage.updateAuthentication(userKey, authentication);
    }

    public boolean verify(String token) {
        return StrUtil.isNotBlank(getUserKey(token));
    }

    public List<SecurityToken> getUserToToken(String client, String userId) {
        return tokenStorage.getToken(SecurityTool.userKey(client, userId));
    }

    public String getUserKey(String token) {
        return tokenStorage.getUserKey(token);
    }

    public String getKickCause(String token) {
        return tokenStorage.getkickCause(token);
    }

    public RefreshStorage getRefreshStorage(String refreshToken) {
        return tokenStorage.getRefreshTokenStorage(refreshToken);
    }

    /**
     * 按 token 剔出
     */
    public void kick(String token, String cause) {
        tokenStorage.kick(token, cause);
    }

    /**
     * 按 user_key 剔出，目前该方法不支持二级缓存
     */
    public void kickUserKey(String client, String userId, String cause) {
        tokenStorage.kickUserKey(SecurityTool.userKey(client, userId), cause);
    }
}
